import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sports_new/base/base_controller.dart';
import 'package:sports_new/resources/styles.dart';

typedef Builder<T extends DisposableInterface> = Widget Function(
  T logic,
  BuildContext context,
  ScrollPhysics physics,
);

class RefreshBuilder<T extends BaseController> extends StatefulWidget {
  const RefreshBuilder({
    super.key,
    required this.builder,
    this.scrollController,
    this.header,
    this.footer,
    this.tag,
    this.global = true,
    this.autoRemove = true,
    this.assignId = false,
    this.id,
    this.filter, this.initState,
    this.dispose,
    this.didChangeDependencies,
    this.didUpdateWidget,
    this.init, this.refreshController,
    this.needLoad = false
  });

  final Builder<T> builder;
  final EasyRefreshController? refreshController;
  final ScrollController? scrollController;
  final Header? header;
  final Footer? footer;
  final bool global;
  final Object? id;
  final String? tag;
  final bool autoRemove;
  final bool assignId;
  final bool needLoad;
  final Object Function(T value)? filter;
  final void Function(RefreshBuilderState<T> state)? initState,
      dispose,
      didChangeDependencies;
  final void Function(RefreshBuilder oldWidget, RefreshBuilderState<T> state)?
  didUpdateWidget;
  final T? init;

  @override
  RefreshBuilderState<T> createState() => RefreshBuilderState<T>();
}

class RefreshBuilderState<T extends BaseController> extends State<RefreshBuilder<T>>
    with GetStateUpdaterMixin {
  T? controller;
  bool? _isCreator = false;
  VoidCallback? _remove;
  Object? _filter;

  @override
  void initState() {
    // _GetBuilderState._currentState = this;
    super.initState();
    widget.initState?.call(this);

    var isRegistered = GetInstance().isRegistered<T>(tag: widget.tag);

    if (widget.global) {
      if (isRegistered) {
        if (GetInstance().isPrepared<T>(tag: widget.tag)) {
          _isCreator = true;
        } else {
          _isCreator = false;
        }
        controller = GetInstance().find<T>(tag: widget.tag);
      } else {
        controller = widget.init;
        _isCreator = true;
        GetInstance().put<T>(controller!, tag: widget.tag);
      }
    } else {
      controller = widget.init;
      _isCreator = true;
      controller?.onStart();
    }

    if (widget.filter != null) {
      _filter = widget.filter!(controller!);
    }

    _subscribeToController();
  }

  /// Register to listen Controller's events.
  /// It gets a reference to the remove() callback, to delete the
  /// setState "link" from the Controller.
  void _subscribeToController() {
    _remove?.call();
    _remove = (widget.id == null)
        ? controller?.addListener(
      _filter != null ? _filterUpdate : getUpdate,
    )
        : controller?.addListenerId(
      widget.id,
      _filter != null ? _filterUpdate : getUpdate,
    );
  }

  void _filterUpdate() {
    var newFilter = widget.filter!(controller!);
    if (newFilter != _filter) {
      _filter = newFilter;
      getUpdate();
    }
  }

  @override
  void dispose() {
    super.dispose();
    widget.dispose?.call(this);
    if (_isCreator! || widget.assignId) {
      if (widget.autoRemove && GetInstance().isRegistered<T>(tag: widget.tag)) {
        GetInstance().delete<T>(tag: widget.tag);
      }
    }

    _remove?.call();

    controller = null;
    _isCreator = null;
    _remove = null;
    _filter = null;
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    widget.didChangeDependencies?.call(this);
  }

  @override
  void didUpdateWidget(RefreshBuilder oldWidget) {
    super.didUpdateWidget(oldWidget as RefreshBuilder<T>);
    // to avoid conflicts when modifying a "grouped" id list.
    if (oldWidget.id != widget.id) {
      _subscribeToController();
    }
    widget.didUpdateWidget?.call(oldWidget, this);
  }

  @override
  Widget build(BuildContext context) {
    return EasyRefresh.builder(
      controller: controller?.refreshController,
      scrollController: widget.scrollController,
      header: widget.header ?? Styles.refreshHeader(),
      footer: widget.footer ?? Styles.refreshFooter(),
      onRefresh: controller?.getRefresh,
      onLoad: widget.needLoad?controller?.loadMore:null,
      childBuilder: (BuildContext context, ScrollPhysics physics){
        return widget.builder(controller!,context, physics);
      }
    );
  }
}

// class BaseBuilder<T extends BaseController> extends StatefulWidget {
//   const BaseBuilder({super.key, required this.builder, required this.scrollController, this.header, this.footer, this.tag});
//
//   final Builder builder;
//   final String? tag;
//   final ScrollController scrollController;
//   final Header? header;
//   final Footer? footer;
//
//   @override
//   BaseBuilderState<T> createState() => BaseBuilderState<T>();
// }
//
// class BaseBuilderState<T extends BaseController> extends State<BaseBuilder<T>> {
//   @override
//   Widget build(BuildContext context) {
//     return GetBuilder<T>(
//       tag: widget.tag,
//       builder: (T controller) {
//         return EasyRefresh.builder(
//           controller: controller.refreshController,
//           scrollController: widget.scrollController,
//           header: widget.header ?? Styles.refreshHeader(),
//           footer: widget.footer ?? Styles.refreshFooter(),
//           onRefresh: controller.getRefresh,
//           onLoad: controller.loadMore,
//           childBuilder: (BuildContext context, ScrollPhysics physics){
//             return widget.builder(context, physics,controller);
//           }
//         );
//       },
//     );
//   }
// }
